#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std;

constexpr int START = 100;
constexpr int END = 300;
constexpr int N = 4; // 线程数

int cnt = 0;
mutex cnt_mutex;

int job = 0;
mutex job_mutex; // 互斥量
condition_variable job_cond; // 状态变量

bool is_prime(int n) {
	int i;

    if (n <= 1)
		return false;

    for (i = 2; i <= n/2; ++i) {
        if (n % i == 0) return false;
    }
    return true;
}

void worker_thread() {
	int value;

    while (true) {
        unique_lock<mutex> job_lock(job_mutex);

        job_cond.wait(job_lock, []{ return job != 0; });

        if (job == -1) {
            job_lock.unlock();
            break;
        }

        value = job;
        job = 0;
        job_lock.unlock();
        job_cond.notify_all();

        if (is_prime(value)) {
            unique_lock<mutex> cnt_lock(cnt_mutex);
            ++cnt;
            cout << value << " is a prime number\n";

			cnt_lock.unlock();
        }
    }
}

int main() {
    thread threads[N];
	int i;

    // 创建工作线程
    for (i = 0; i < N; i++) {
        threads[i] = thread(worker_thread);
    }

    // 分配任务
    for (i = START; i <= END; i++) {
        unique_lock<mutex> job_lock(job_mutex);
        job_cond.wait(job_lock, []{ return job <= 0; });

        job = i;
        job_lock.unlock();
        job_cond.notify_one(); // pthread_cond_signal
    }

    // 等待最后一个任务完成
    {
        unique_lock<mutex> job_lock(job_mutex);
        job_cond.wait(job_lock, []{ return job <= 0; });
        job = -1;
        job_lock.unlock();
        job_cond.notify_all();
    }

    // 等待所有工作线程结束
    for (i = 0; i < N; i++) {
        threads[i].join();
    }

    cout << "共有" << cnt << "个质数" << endl;

    return 0;
}
